package com.pinhuba.bams.framework.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.pinhuba.bams.framework.ConfigProperties;
import com.pinhuba.bams.framework.ErrorCode;
import com.pinhuba.bams.framework.UrlType;
import com.pinhuba.bams.framework.exception.AirPlaneModeException;
import com.pinhuba.bams.framework.exception.NoInternetException;
import com.pinhuba.bams.framework.util.FileUtils;
import com.pinhuba.bams.framework.util.Loger;
import com.pinhuba.bams.framework.util.PhoneStateUtil;

public class AsynUpgrade extends AsyncTask<UrlType, Integer, Integer> {
	protected HashMap<String, String> params;
	protected Context context;
	protected ErrorListener errorListener;
	protected String filePath;
	protected String apkURL;
	protected ErrorCode errorCode;
	protected FileUtils fileUtils;
	protected TextView tv;
	protected ProgressBar pb;

	public AsynUpgrade(Context context, ErrorListener errorlistener, String filePath, String apkURL, TextView tv, ProgressBar pb, HashMap<String, String> params) {
		errorCode = ErrorCode.SUCCESS;
		this.context = context;
		this.errorListener = errorlistener;
		this.filePath = filePath;
		this.apkURL = apkURL;
		this.tv = tv;
		this.pb = pb;
		this.params = params;
	}

	@Override
	protected Integer doInBackground(UrlType... urlTypes) {
		InputStream is = null;
		OutputStream os = null;
		HttpURLConnection conn = null;
		int progress = 0;
		try {
			PhoneStateUtil.checkNetWork();
		} catch (AirPlaneModeException e) {
			e.printStackTrace();
			errorCode = ErrorCode.AIRPLANE_MODE;
		} catch (NoInternetException e) {
			e.printStackTrace();
			errorCode = ErrorCode.NO_INTERNET;
		}
		if (errorCode != ErrorCode.SUCCESS) {
			return 0;
		}

		if (!fileUtils.isSDExist()) {
			errorCode = ErrorCode.NOSDCARD;
			return 0;
		}

		File file = new File(filePath);

		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdir();
		}

		if (file.exists()) {
			file.delete();
		}

		try {
			URL url = new URL(this.apkURL);
			conn = (HttpURLConnection) url.openConnection();
			conn.connect();
			conn.setConnectTimeout(ConfigProperties.TIMEOUT);
			
			int contentlength = conn.getContentLength();
			Loger.d("The length is :" + contentlength);
			if (contentlength <= 0) {
				if (conn != null) {
					conn.disconnect();
				}
				errorCode = ErrorCode.INVALID_REQUEST;
				return 0;
			}

			is = conn.getInputStream();
			int hasRead = 0;
			byte[] bs = new byte[1024 * 16];
			int len;
			os = new FileOutputStream(file);
			// 开始读取
			int progressBefore = 0;
			publishProgress(progress);
			while ((len = is.read(bs)) != -1) {
				if (isCancelled()) {

					Loger.d("The in back is cancel");
					if (is != null) {
						is.close();
					}
					if (os != null) {
						os.close();
					}

					if (conn != null) {
						conn.disconnect();
					}
					return 0;
				}

				os.write(bs, 0, len);
				hasRead += len;
				Loger.d("The num is:" + hasRead);
				progress = (int) ((double) hasRead / (double) contentlength * 100);
				if (hasRead > progressBefore) {
					progressBefore = hasRead;
					publishProgress(progress);
				}
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
			errorCode = ErrorCode.INVALID_REQUEST;
		} catch (IOException e) {
			e.printStackTrace();
			errorCode = ErrorCode.INVALID_IO;
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					errorCode = ErrorCode.INVALID_IO;
				}
			}
			if (os != null) {
				try {
					os.flush();
					os.close();
				} catch (IOException e) {
					errorCode = ErrorCode.INVALID_IO;
				}
			}

			if (conn != null) {
				conn.disconnect();
			}
		}

		if (errorCode == ErrorCode.SUCCESS) {
			if (progress == 100) {
				return 1;
			} else {
				errorCode = ErrorCode.UNKNOWN_EXCEPTION;
				if (file.exists()) {
					if (!file.delete()) {
						errorCode = ErrorCode.INVALID_IO;
					}
				}
				return 0;
			}
		} else {
			return 0;
		}

	}

	@Override
	protected void onCancelled() {
		AsynUpgrade.this.cancel(true);
		Loger.d("The canceled is");
		super.onCancelled();
	}

	protected void onPostExecute(Integer result) {
		if (result == 1) {
			errorListener.onSuccess(null, null);
		} else {
			errorListener.onError(null, errorCode);
		}

		super.onPostExecute(result);
	}

	protected void onPreExecute() {
		fileUtils = new FileUtils();
		super.onPreExecute();
	}

	protected void onProgressUpdate(Integer... values) {
		Loger.d("The value in onProgressUpdate is" + values[0]);
		this.tv.setText(values[0] + "%");
		this.pb.setProgress(values[0]);
		super.onProgressUpdate(values);
	}
}
